package com.itheima.ydd.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.ydd.common.R;
import com.itheima.ydd.common.ResultData;
import com.itheima.ydd.dto.YddArticleDto;
import com.itheima.ydd.entity.*;
import com.itheima.ydd.service.*;
import com.itheima.ydd.utils.JwtUtils;
import com.sun.javaws.jnl.InformationDesc;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author author
 * @since 2022-05-22
 */
@RestController
@RequestMapping("/index")
@Slf4j
@CrossOrigin
public class SysUserController {
    @Autowired
    private IYddArticleService yddArticleService;

    @Autowired
    private IYddCateService yddCateService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IYddTagService yddTagService;
    @Autowired
    private IYddLinkService yddLinkService;
    @Autowired
    private IYddAdvimgService yddAdvimgService;
    @Autowired
    private IYddAdvposService yddAdvposService;

    @Autowired
    private IYddUserService yddUserService;

    @PostMapping("/login")
    public R login(@RequestBody SysUser sysUser) {
        log.info("登陆用户：{}", sysUser.toString());

        String loginName = sysUser.getLoginName();
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getLoginName, loginName);
        SysUser one = sysUserService.getOne(wrapper);

        if (one == null) {
            return R.error("账号不存在");
        } else if (one.getStatus() == 0) {
            return R.error("账号已禁用");
        }

        String password = sysUser.getPassword();
        if (one.getPassword().equals(generatePassword(password))) {
            //把用户id 加密进token里

            // 生成token信息
            Map retMap = new HashMap();
            Map tokenMap = new HashMap<>();
            String roleId = one.getRoleId()
                    .replace("[", "")
                    .replace("]", "")
                    .replace("\"", "");

            tokenMap.put("userId", one.getId());
            tokenMap.put("roleId", roleId);

            String token = JwtUtils.getToken(tokenMap);
            retMap.put("token", token);
            return R.success("token", JwtUtils.getToken(tokenMap));
        }
        return R.error("密码错误");

    }


    @GetMapping("/getConfig")
    public R systemConfig() {
        LambdaQueryWrapper<SysConfig> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysConfig::getTabValue, "system");
        List<SysConfig> sysConfigs = sysConfigService.list(wrapper);

        HashMap<String, String> map = new HashMap<>();
        for (SysConfig sysConfig : sysConfigs) {
            map.put(sysConfig.getAttrKey(), sysConfig.getAttrValue());
        }

        return new R(map, "", 0);

    }

    @PostMapping("/profile")
    public R profile(HttpServletRequest request) {
        String token = request.getHeader("x-token");

        Claims claims = JwtUtils.getClaims(token);
        Long userId = Long.valueOf((String) claims.get("userId"));

        log.info("用户id:{}", userId);
        return sysUserService.profile(userId);
    }

    /**
     * md5加密
     *
     * @param password 密码
     */
    private String generatePassword(String password) {
        return DigestUtils.md5DigestAsHex(password.getBytes());
    }

    @GetMapping("baseInfo")
    public ResultData baseInfo() {
        return sysUserService.baseInfo();
    }

    /**
     * 热门置顶文章数据
     *
     * @return
     */
    @GetMapping("/new")
    public ResultData getHotAndTop(int page, int limit) {
        //ResultData属性data
        Map<String, Object> data = new HashMap<>();
        //分页数据
        Page<YddArticle> pageInfo = new Page<>(page, limit);
        yddArticleService.page(pageInfo);

        Map<String, Object> list = new HashMap<>();
        list.put("data", pageInfo.getRecords());
        list.put("totalPages", pageInfo.getPages());
        list.put("currentPage", pageInfo.getCurrent());
        list.put("pageSize", pageInfo.getSize());
        list.put("count", pageInfo.getTotal());

        //24小时最新文章数量
        LambdaQueryWrapper<YddArticle> lqw = new LambdaQueryWrapper<>();
        lqw.between(YddArticle::getUpdateDate, System.currentTimeMillis(), System.currentTimeMillis() - 24 * 60 * 60 * 1000);
        int num_day = yddArticleService.count(lqw);

        //一周文章最新数量
        LambdaQueryWrapper<YddArticle> qw = new LambdaQueryWrapper<>();
        qw.between(YddArticle::getUpdateDate, System.currentTimeMillis(), System.currentTimeMillis() - 7 * 24 * 60 * 60 * 1000);
        int num_week = yddArticleService.count(qw);

        //data中所需数据
        data.put("list", list);
        data.put("desc", "首页大列表");
        data.put("num_day", num_day);
        data.put("num_week", num_week);

        return ResultData.ok("成功", data);
    }

    /**
     * 文章列表数据
     *
     * @return
     */
    @GetMapping("/list")
    public ResultData list(int page, int limit, int cateid) {
        //ResultData属性data
        Map<String, Object> data = new HashMap<>();
        //分页数据
        Page<YddArticle> pageInfo = new Page<>(page, limit);
        LambdaQueryWrapper<YddArticle> lqw = new LambdaQueryWrapper<>();
        lqw.eq(YddArticle::getCateid, cateid);
        yddArticleService.page(pageInfo, lqw);

        Map<String, Object> list = new HashMap<>();
        List<YddArticle> records = pageInfo.getRecords();
        LambdaQueryWrapper<YddCate> qw = new LambdaQueryWrapper<>();
        qw.select(YddCate::getCatename);
        qw.eq(YddCate::getId, cateid);
        Map<String, Object> map = yddCateService.getMap(qw);
        List<YddArticleDto> yddArticleDtoList = records.stream().map(yddArticle -> {
            YddArticleDto yddArticleDto = new YddArticleDto();
            BeanUtils.copyProperties(yddArticle, yddArticleDto);
            yddArticleDto.setCatename(map.get("catename").toString());
            return yddArticleDto;
        }).collect(Collectors.toList());


        list.put("data", yddArticleDtoList);
        list.put("totalPages", pageInfo.getPages());
        list.put("currentPage", pageInfo.getCurrent());
        list.put("pageSize", pageInfo.getSize());
        list.put("count", pageInfo.getTotal());

        data.put("list", list);
        return ResultData.ok("", data);
    }



    /**
     * 最新文章
     *
     * @return
     */
    @GetMapping("/hot")
    public ResultData hot() {
        Map<String, Object> data = new HashMap<>();
        data.put("desc", "侧边最新文章");

        LambdaQueryWrapper<YddArticle> lqw = new LambdaQueryWrapper<>();
        lqw.select(YddArticle::getId, YddArticle::getTitle, YddArticle::getPic, YddArticle::getLovenum, YddArticle::getCateid);
        lqw.last("limit 8");
        List<Map<String, Object>> listMaps = yddArticleService.listMaps(lqw);
        for (Map<String, Object> map : listMaps) {
            LambdaQueryWrapper<YddCate> qw = new LambdaQueryWrapper<>();
            qw.select(YddCate::getCatename).eq(YddCate::getId, map.get("cateid"));
            Map<String, Object> map1 = yddCateService.getMap(qw);
            map.put("catename", map1.get("catename"));
        }
        data.put("list", listMaps);
        return ResultData.ok("", data);
    }

    /**
     * 推荐文章
     *
     * @return
     */
    @GetMapping("/recommend")
    public ResultData recommend() {
        Map<String, Object> data = new HashMap<>();
        data.put("desc", "侧边推荐文章");

        LambdaQueryWrapper<YddArticle> lqw = new LambdaQueryWrapper<>();
        lqw.select(YddArticle::getClick, YddArticle::getId, YddArticle::getTitle, YddArticle::getPic, YddArticle::getLovenum, YddArticle::getCateid);
        lqw.last("limit 5");
        List<Map<String, Object>> listMaps = yddArticleService.listMaps(lqw);
        for (Map<String, Object> map : listMaps) {
            LambdaQueryWrapper<YddCate> qw = new LambdaQueryWrapper<>();
            qw.select(YddCate::getCatename).eq(YddCate::getId, map.get("cateid"));
            Map<String, Object> map1 = yddCateService.getMap(qw);
            map.put("catename", map1.get("catename"));
        }
        data.put("list", listMaps);
        return ResultData.ok("", data);
    }

    /**
     * 首页和全局数据
     *
     * @return
     */
    @GetMapping("/index")
    public ResultData index() {
        Map<String, Object> data = new HashMap<>();
        //allCate
        LambdaQueryWrapper<YddCate> yddCateLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddCateLambdaQueryWrapper.select(YddCate::getId, YddCate::getCatename, YddCate::getIcon, YddCate::getSortNum);
        List<Map<String, Object>> yddCates = yddCateService.listMaps(yddCateLambdaQueryWrapper);
        data.put("allCate", yddCates);

        //config
        Map<String, List> config = new HashMap<>();
        //config : list
        List<Map<String, Object>> list = new ArrayList<>();
        config.put("list", list);
        //config : allData
        LambdaQueryWrapper<SysConfig> sysConfigLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysConfigLambdaQueryWrapper.select(SysConfig::getId, SysConfig::getAttrKey, SysConfig::getAttrValue, SysConfig::getValidator, SysConfig::getConfigValue, SysConfig::getType);
        List<Map<String, Object>> allData = sysConfigService.listMaps(sysConfigLambdaQueryWrapper);
        config.put("allData", allData);

        data.put("config", config);

        //allTag
        LambdaQueryWrapper<YddTag> yddTagLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddTagLambdaQueryWrapper.select(YddTag::getId, YddTag::getTagname);
        List<Map<String, Object>> allTag = yddTagService.listMaps(yddTagLambdaQueryWrapper);
        data.put("allTag", allTag);

        //allLink
        LambdaQueryWrapper<YddLink> yddLinkLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddLinkLambdaQueryWrapper.select(YddLink::getId, YddLink::getTitle, YddLink::getUrl, YddLink::getDes, YddLink::getImg, YddLink::getType);
        List<Map<String, Object>> allLink = yddLinkService.listMaps(yddLinkLambdaQueryWrapper);
        data.put("allLink", allLink);

        //banner
        LambdaQueryWrapper<YddAdvimg> yddAdvimgLambdaQueryWrapper = new LambdaQueryWrapper<>();
        yddAdvimgLambdaQueryWrapper.eq(YddAdvimg::getAdvimgpos, 15);
        List<YddAdvimg> banner = yddAdvimgService.list(yddAdvimgLambdaQueryWrapper);
        data.put("banner", banner);

        //sideBanner
        LambdaQueryWrapper<YddAdvimg> yddAdvimgLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        yddAdvimgLambdaQueryWrapper1.eq(YddAdvimg::getAdvimgpos, 14);
        List<YddAdvimg> sideBanner = yddAdvimgService.list(yddAdvimgLambdaQueryWrapper1);
        data.put("sideBanner", sideBanner);

        //showBanner
        LambdaQueryWrapper<YddAdvimg> yddAdvimgLambdaQueryWrapper2 = new LambdaQueryWrapper<>();
        yddAdvimgLambdaQueryWrapper2.eq(YddAdvimg::getAdvimgpos, 13).or().eq(YddAdvimg::getAdvimgpos, 12);
        List<YddAdvimg> showBanner = yddAdvimgService.list(yddAdvimgLambdaQueryWrapper2);
        data.put("showBanner", showBanner);

        return ResultData.ok("", data);
    }

    /**
     * 文章详情数据
     *
     * @return
     */
    @GetMapping("/show")
    public ResultData show(int id) {
        Map<String, Object> data = new HashMap<>();
        //上一篇
        LambdaQueryWrapper<YddArticle> lqw = new LambdaQueryWrapper<>();
        lqw.select(YddArticle::getId, YddArticle::getTitle);
        lqw.lt(YddArticle::getId, id).orderByDesc(YddArticle::getId).last("limit 0,1");
        Map<String, Object> prev = yddArticleService.getMap(lqw);
        data.put("prev", prev);
        //下一篇
        LambdaQueryWrapper<YddArticle> qw = new LambdaQueryWrapper<>();
        qw.select(YddArticle::getId, YddArticle::getTitle);
        qw.gt(YddArticle::getId, id).orderByAsc(YddArticle::getId).last("limit 0,1");
        Map<String, Object> next = yddArticleService.getMap(qw);
        data.put("next", next);

        //info
        YddArticle yddArticle = yddArticleService.getById(id);
        YddArticleDto info = new YddArticleDto();
        LambdaQueryWrapper<YddCate> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YddCate::getId, yddArticle.getCateid()).select(YddCate::getCatename);
        Map<String, Object> catename = yddCateService.getMap(wrapper);
        BeanUtils.copyProperties(yddArticle, info);
        info.setCatename(catename.get("catename").toString());
        data.put("info", info);

        //recommend
        LambdaQueryWrapper<YddArticle> rqw = new LambdaQueryWrapper<>();
        rqw.select(YddArticle::getId, YddArticle::getTitle, YddArticle::getPic, YddArticle::getCateid);
        rqw.last("limit 0,8");
        List<Map<String, Object>> recommend = yddArticleService.listMaps(rqw);
        data.put("recommend", recommend);

        return ResultData.ok("", data);
    }


    //注册
    @PostMapping("reg")
    private ResultData reg(@RequestBody YddUser yddUser) {
        //判断电话号码是否存在

        //创建查询构造器
        LambdaQueryWrapper<YddUser> lqw = new LambdaQueryWrapper<>();
        //创建条件查询
        lqw.eq(YddUser::getMobile, yddUser.getMobile());
        YddUser one = yddUserService.getOne(lqw);
        if (one == null) {
            //对数据进行非空判断
            if (yddUser.getMobile() != null && yddUser.getPassword() != null && yddUser.getPassword().length() != 0) {
                //创建用户对象
                YddUser user = new YddUser();
                //填入数据
                String generatePassword = generatePassword(yddUser.getPassword());
                user.setMobile(yddUser.getMobile());
                user.setUsername(yddUser.getMobile());
                user.setPassword(generatePassword);
                //添加
                boolean save = yddUserService.save(user);
                return ResultData.ok("注册成功", user);
            }
        }
        return ResultData.error("用户名已存在");
    }
}
